package wili.b1;

import java.util.List;
import java.util.Map;
import java.util.function.Predicate;
import java.util.stream.Collectors;

import wili.attrMapping._user.b1.exp.AndOrExp2;
import wili.attrMapping._user.b1.exp.AndOrNode2;
import wili.attrMapping._user.b1.exp.Funb1;
import wili.attrMapping._user.b1.exp.MathExpB1;
import wili.attrMapping._user.b1.exp.Valueb1;
import wili.attrMapping._user.b1.exp.Varb1;

/**
 *
 */
public class FormulaTransform4b1 {
	AndOrExp2 andOrExp;

	FormulaTransform4b1(String expSt) {
		this.andOrExp = AndOrExp2.newInst(-1, expSt);
	}

	public static String transform___(String expSt) {
		// Ca.pause();
		String ret = new FormulaTransform4b1(expSt).transform();
		return ret;
	}

	String transform() {
		IncludesFun9.includesFun_transform(this.andOrExp.rootNode);
		return andOrExp.rootNode.getString(1);
	}

	Predicate<AndOrNode2> getTransformer_manyEq_to_includes() {
		return new Predicate<AndOrNode2>() {
			@Override
			public boolean test(AndOrNode2 node) {
				// and {/VContInvnt} eq 'Y'
				if (node.isAnd == null || node.isAnd)
					return false;
				{//把或式中的多个eq子，转成includes函数。eg. {ObjType} eq 2 or {ObjType} eq 3 ~>[2,3].includes({ObjType})
				 //({ObjType} eq 15 or {ObjType} eq 23 or {ObjType} eq 17) and {/DocType} eq 'I'
					List<AndOrNode2> sons = node.sons;
					if ("".isEmpty()) {
						if (sons.size() < 2)
							return false;
						List<AndOrNode2> eqList = sons.stream()
								.filter(e -> e.mathExp != null && e.mathExp.op.matches("===|eq"))
								.collect(Collectors.toList());
						Map<String, List<AndOrNode2>> varToEqNodesMap = AndOrNode2.groupList(eqList, (nod) -> {
							MathExpB1 exp = nod.mathExp;
							if (exp.ll instanceof Varb1) {
								if (exp.rr instanceof Valueb1)
									return exp.ll.getString(1);
							} else if (exp.ll instanceof Valueb1) {
								if (exp.rr instanceof Varb1)
									return exp.rr.getString(1);
							}
							return null;
						});
						//有多个eq子左侧是相同变量，右侧是值。
						for (List<AndOrNode2> eqNodes : varToEqNodesMap.values()) {
							if (eqNodes.size() >= 2) {
								AndOrNode2 firstSon = eqNodes.get(0);
								sons.removeAll(eqNodes.subList(1, eqNodes.size()));
								List<MathExpB1> includesSons = eqNodes.stream().map(e -> e.mathExp)
										.collect(Collectors.toList());
								firstSon.mathExp = Funb1.newInst_includesFun(includesSons);
							}
						}
						if (sons.size() == 1) {
							node.toString();
							node.setMathExp(sons.get(0).mathExp);
						}
					}
				}
				return true;
			}
		};
	}

	public static void test() {
		IncludesFun9.test();
	}

	public static void main(String[] args) {
		test();
	}
}
